package action

import (
	"github.com/jacktea/z-cron/common"
	"github.com/jacktea/z-cron/service"
	"github.com/labstack/echo/v4"
	"net/http"
	"time"
)

type TaskReq struct {
	Id         int64  `json:"id" form:"id" query:"id"`
	AppId      string `json:"appId" form:"appId" query:"appId"`
	TaskId     string `json:"taskId" form:"taskId" query:"taskId"`
	Notify     string `json:"notify" form:"notify" query:"notify"`
	Spec       string `json:"spec" form:"spec" query:"spec"`
	Delay      int64  `json:"delay" form:"durationTime" query:"durationTime"`
	ActionTime int64  `json:"actionTime" form:"actionTime" query:"actionTime"`
}

type TaskResp struct {
	ErrorCode    int64               `json:"errorCode"`
	ErrorMessage string              `json:"errorMessage"`
	Data         *service.TaskInfo   `json:"data,omitempty"`
	Results      []*service.TaskInfo `json:"results,omitempty"`
}

func respError(c echo.Context, errorCode int64, errorMessage string) error {
	return c.JSON(http.StatusOK, map[string]interface{}{
		"errorCode":    errorCode,
		"errorMessage": errorMessage,
	})
}

var pool = service.NewTaskPool()

func AddTask(c echo.Context) error {
	//fmt.Println("add Task")
	req := new(TaskReq)
	if err := c.Bind(req); err != nil {
		return respError(c, common.ErrorReqParse, err.Error())
	} else {
		spec := req.Spec
		timeout := req.Delay
		if spec == "" {
			if timeout <= 0 {
				timeout = req.ActionTime - time.Now().Unix()
			}
			if timeout <= 0 {
				return respError(c, common.ErrorBusiness, "time is out")
			}
		}
		id, err := pool.AddTask(req.AppId, req.TaskId, req.Notify, req.Spec, time.Now().Add(time.Duration(timeout)*time.Second))
		if err != nil {
			return respError(c, 11020, err.Error())
		} else {
			return c.JSON(http.StatusOK, map[string]interface{}{
				"errorCode":    0,
				"errorMessage": "OK",
				"data":         id,
			})
		}
	}
}

func DeleteTask(c echo.Context) error {
	req := new(TaskReq)
	if err := c.Bind(req); err != nil {
		return respError(c, common.ErrorReqParse, err.Error())
	}
	if req.Id > 0 {
		pool.RemoveTaskById(req.Id)
	} else {
		pool.RemoveTask(req.AppId, req.TaskId)
	}
	return c.JSON(http.StatusOK, map[string]interface{}{
		"errorCode":    0,
		"errorMessage": "OK",
	})
}

func GetTask(c echo.Context) error {
	req := new(TaskReq)
	if err := c.Bind(req); err != nil {
		return respError(c, common.ErrorReqParse, err.Error())
	}
	if req.Id > 0 {
		if info, err := pool.GetTaskById(req.Id); err != nil {
			return respError(c, common.ErrorBusiness, err.Error())
		} else {
			return c.JSON(http.StatusOK, TaskResp{
				ErrorCode:    0,
				ErrorMessage: "OK",
				Data:         info,
			})
		}
	} else {
		if info, err := pool.GetTask(req.AppId, req.TaskId); err != nil {
			return respError(c, common.ErrorBusiness, err.Error())
		} else {
			return c.JSON(http.StatusOK, TaskResp{
				ErrorCode:    0,
				ErrorMessage: "OK",
				Data:         info,
			})
		}
	}
}

func GetTaskList(c echo.Context) error {
	req := new(TaskReq)
	if err := c.Bind(req); err != nil {
		return respError(c, common.ErrorReqParse, err.Error())
	}
	list, _ := pool.GetTaskList(req.AppId)
	return c.JSON(http.StatusOK, TaskResp{
		ErrorCode:    0,
		ErrorMessage: "OK",
		Results:      list,
	})
}
